<template>
  <div class="illustration-detail">
    <!-- 分类头部信息 -->
    <div class="category-header">
      <div class="container">
        <div class="header-content">
          <div class="header-info">
            <h1 class="category-title">{{ categoryInfo.title || '分类详情' }}</h1>
            <p class="category-description" v-if="categoryInfo.description">
              {{ categoryInfo.description }}
            </p>
            <div class="category-stats">
              <span class="stats-item">
                <span class="stats-label">插画数量:</span>
                <span class="stats-value">{{ illustrations.length || 0 }}</span>
              </span>
              <span class="stats-item" v-if="categoryInfo.created_at">
                <span class="stats-label">创建时间:</span>
                <span class="stats-value">{{ formatDate(categoryInfo.created_at) }}</span>
              </span>
            </div>
          </div>

          <!-- 管理员操作按钮 -->
          <div v-if="isAdmin" class="header-actions">
            <a-upload :show-upload-list="false" :custom-request="handleQuickUpload" accept=".svg" :disabled="uploading" :multiple="true">
              <a-button type="primary" :loading="uploading">
                <template #icon>
                  <UploadOutlined />
                </template>
                上传插画
              </a-button>
            </a-upload>
          </div>
        </div>
      </div>
    </div>

    <!-- 插画网格 -->
    <div class="illustrations-section">
      <div class="container">
        <!-- 加载状态 -->
        <div v-if="loading" class="loading-container">
          <a-spin size="large" />
        </div>

        <!-- 插画网格 -->
        <div v-else-if="illustrations.length > 0" class="illustrations-grid">
          <div class="illustration-card" v-for="illustration in illustrations" :key="illustration.id" @click="handleIllustrationClick(illustration)">
            <!-- 管理员删除按钮 -->
            <div v-if="isAdmin" class="illustration-actions" @click="stopPropagation">
              <a-button type="text" size="small" danger @click="handleDeleteIllustration(illustration)" title="删除插画" :loading="deletingIds.includes(illustration.id)">
                <template #icon>
                  <DeleteOutlined />
                </template>
              </a-button>
            </div>

            <div class="illustration-image">
              <img :src="getIllustrationUrl(illustration.file_path)" :alt="illustration.original_name" @error="handleImageError" @contextmenu="preventImageContextMenu" draggable="false" style="user-select: none; -webkit-user-drag: none" />
            </div>
            <div class="illustration-info">
              <h3 class="illustration-title" :title="illustration.original_name">
                {{ illustration.original_name }}
              </h3>
              <p class="illustration-meta">{{ formatFileSize(illustration.file_size) }} • {{ formatDate(illustration.created_at) }}</p>

              <!-- 操作菜单 -->
              <div class="illustration-menu" @click="stopPropagation">
                <a-dropdown placement="bottom" :trigger="['hover']">
                  <a-button type="text" size="small" class="menu-trigger">
                    <template #icon>
                      <MoreOutlined />
                    </template>
                  </a-button>
                  <template #overlay>
                    <a-menu>
                      <a-menu-item key="copy" @click="handleCopySVG(illustration)">
                        <template #icon>
                          <CopyOutlined />
                        </template>
                        复制SVG
                      </a-menu-item>
                      <a-menu-item key="download-svg" @click="handleDownloadSVG(illustration)">
                        <template #icon>
                          <DownloadOutlined />
                        </template>
                        下载SVG
                      </a-menu-item>
                      <a-menu-item key="download-png" @click="handleDownloadPNG(illustration)">
                        <template #icon>
                          <FileImageOutlined />
                        </template>
                        下载PNG
                      </a-menu-item>
                      <a-menu-item key="copy-vue3" @click="handleCopyAsVue3Component(illustration)">
                        <template #icon>
                          <CopyOutlined />
                        </template>
                        复制成Vue3组件
                      </a-menu-item>
                    </a-menu>
                  </template>
                </a-dropdown>
              </div>
            </div>
          </div>
        </div>

        <!-- 空状态 -->
        <div v-else class="empty-state">
          <a-empty description="该分类下暂无插画">
            <div v-if="isAdmin" class="empty-actions">
              <a-upload :show-upload-list="false" :custom-request="handleQuickUpload" accept=".svg" :disabled="uploading" :multiple="true">
                <a-button type="primary" :loading="uploading"> 上传插画 </a-button>
              </a-upload>
            </div>
          </a-empty>
        </div>
      </div>
    </div>

    <!-- 插画预览弹窗 -->
    <a-modal v-model:open="previewVisible" :title="currentIllustration?.original_name" :footer="null" :width="Math.max(600, '80vw')" :style="{ top: '20px' }" :body-style="{ padding: '20px', textAlign: 'center', minWidth: '500px' }">
      <div class="preview-content" v-if="currentIllustration">
        <img :src="getIllustrationUrl(currentIllustration.file_path)" :alt="currentIllustration.original_name" class="preview-image" @contextmenu="preventImageContextMenu" draggable="false" style="user-select: none; -webkit-user-drag: none" />
        <div class="preview-info">
          <p><strong>文件名:</strong> {{ currentIllustration.original_name }}</p>
          <p><strong>文件大小:</strong> {{ formatFileSize(currentIllustration.file_size) }}</p>
          <p><strong>上传时间:</strong> {{ formatDate(currentIllustration.created_at) }}</p>
        </div>
      </div>
    </a-modal>
  </div>
</template>

<script setup>
import { ref, onMounted, watch, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { message, Modal } from 'ant-design-vue'
import { UploadOutlined, DeleteOutlined, CopyOutlined, DownloadOutlined, FileImageOutlined, MoreOutlined } from '@ant-design/icons-vue'
import { useUserStore } from '@/stores/user'
import { getCategoryIllustrations, uploadIllustration, deleteIllustration } from '@/utils/api'

const route = useRoute()
const router = useRouter()
const userStore = useUserStore()

// 分类信息
const categoryInfo = ref({
  id: null,
  title: '',
  description: ''
})

// 插画数据
const illustrations = ref([])
const loading = ref(false)
const uploading = ref(false)
const deletingIds = ref([])

// 预览相关
const previewVisible = ref(false)
const currentIllustration = ref(null)

// 快速上传控制
const quickUploadQueue = ref(new Set())

// 权限检查
const isAdmin = ref(false)

/**
 * 检查管理员权限
 */
const checkAdminPermission = () => {
  isAdmin.value = userStore.user && userStore.user.username === 'woaichitudouo'
}

/**
 * 添加登录检查函数
 */
const checkLoginStatus = () => {
  if (!userStore.isAuthenticated) {
    window.dispatchEvent(new CustomEvent('openLogin'))
    return false
  }
  return true
}

/**
 * 获取插画列表
 */
const fetchIllustrations = async () => {
  try {
    loading.value = true
    const response = await getCategoryIllustrations(categoryInfo.value.id)

    if (response.data) {
      illustrations.value = response.data.illustrations || []
    }
  } catch (error) {
    console.error('获取插画列表失败:', error)
    message.error(error.message || '获取插画列表失败')
  } finally {
    loading.value = false
  }
}

/**
 * 获取插画文件URL
 */
const getIllustrationUrl = (filePath) => {
  return `${import.meta.env.VITE_APP_API_BASE_URL}${filePath}`
}

/**
 * 格式化文件大小
 */
const formatFileSize = (bytes) => {
  if (!bytes) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

/**
 * 格式化日期
 */
const formatDate = (dateString) => {
  if (!dateString) return ''
  const date = new Date(dateString)
  return date.toLocaleDateString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  })
}

/**
 * 处理插画点击事件
 */
const handleIllustrationClick = (illustration) => {
  currentIllustration.value = illustration
  previewVisible.value = true
}

/**
 * 快速上传处理
 */
const handleQuickUpload = async (options) => {
  const { file } = options

  // 生成唯一标识
  const uploadId = `${file.name}_${file.size}_${Date.now()}`

  // 如果已经在处理队列中，跳过
  if (quickUploadQueue.value.has(uploadId)) {
    return
  }

  // 添加到处理队列
  quickUploadQueue.value.add(uploadId)

  try {
    // 检查文件类型
    if (!file.type.includes('svg') && !file.name.toLowerCase().endsWith('.svg')) {
      message.error(`${file.name} 不是SVG格式文件`)
      return
    }

    // 检查文件大小 (10MB)
    if (file.size > 10 * 1024 * 1024) {
      message.error(`${file.name} 文件大小超过10MB`)
      return
    }

    // 如果是第一个文件，设置loading状态
    if (quickUploadQueue.value.size === 1) {
      uploading.value = true
    }

    await uploadIllustration(categoryInfo.value.id, file)
    message.success(`${file.name} 上传成功`)
  } catch (error) {
    console.error('上传插画失败:', error)
    message.error(`${file.name} 上传失败: ${error.message || '未知错误'}`)
  } finally {
    // 从处理队列中移除
    quickUploadQueue.value.delete(uploadId)

    // 如果队列为空，取消loading状态并刷新列表
    if (quickUploadQueue.value.size === 0) {
      uploading.value = false
      await fetchIllustrations()
    }
  }
}

/**
 * 删除插画
 */
const handleDeleteIllustration = (illustration) => {
  Modal.confirm({
    title: '确认删除',
    content: `确定要删除插画 "${illustration.original_name}" 吗？此操作不可恢复。`,
    okText: '确认删除',
    okType: 'danger',
    cancelText: '取消',
    onOk: async () => {
      try {
        deletingIds.value.push(illustration.id)
        await deleteIllustration(illustration.id)
        message.success('插画删除成功')

        // 刷新列表
        await fetchIllustrations()
      } catch (error) {
        console.error('删除插画失败:', error)
        message.error(error.message || '删除插画失败')
      } finally {
        deletingIds.value = deletingIds.value.filter((id) => id !== illustration.id)
      }
    }
  })
}

/**
 * 图片加载错误处理
 */
const handleImageError = (event) => {
  event.target.style.display = 'none'
}

/**
 * 阻止事件冒泡
 */
const stopPropagation = (event) => {
  event.stopPropagation()
}

/**
 * 复制SVG内容
 */
const handleCopySVG = async (illustration) => {
  if (!checkLoginStatus()) return
  if (!illustration) return

  try {
    // 先恢复文档焦点
    window.focus()

    const response = await fetch(getIllustrationUrl(illustration.file_path))
    const svgContent = await response.text()

    await copyToClipboard(svgContent)

    // 使用 nextTick 确保在 Vue 上下文中调用 message
    nextTick(() => {
      message.success(`已复制 ${illustration.original_name} 的SVG内容`)
    })
  } catch (error) {
    console.error('复制SVG失败:', error)
    nextTick(() => {
      message.error('复制SVG失败: ' + (error.message || '未知错误'))
    })
  }
}

/**
 * 下载SVG文件
 */
const handleDownloadSVG = async (illustration) => {
  if (!checkLoginStatus()) return
  if (!illustration) return

  try {
    const response = await fetch(getIllustrationUrl(illustration.file_path))
    const svgContent = await response.text()

    const blob = new Blob([svgContent], { type: 'image/svg+xml' })
    const url = URL.createObjectURL(blob)

    const link = document.createElement('a')
    link.href = url
    link.download = illustration.original_name
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)

    URL.revokeObjectURL(url)
    nextTick(() => {
      message.success(`已下载 ${illustration.original_name}`)
    })
  } catch (error) {
    console.error('下载SVG失败:', error)
    nextTick(() => {
      message.error('下载SVG失败')
    })
  }
}

/**
 * 下载PNG文件
 */
const handleDownloadPNG = async (illustration) => {
  if (!checkLoginStatus()) return
  if (!illustration) return

  try {
    const response = await fetch(getIllustrationUrl(illustration.file_path))
    const svgContent = await response.text()

    // 创建SVG元素
    const svgElement = new DOMParser().parseFromString(svgContent, 'image/svg+xml').documentElement

    // 获取SVG尺寸
    const svgRect = svgElement.getBoundingClientRect()
    const width = svgRect.width || 300
    const height = svgRect.height || 300

    // 创建canvas
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    canvas.width = width * 2 // 2倍分辨率
    canvas.height = height * 2
    ctx.scale(2, 2)

    // 创建图片
    const img = new Image()
    const svgBlob = new Blob([svgContent], { type: 'image/svg+xml;charset=utf-8' })
    const url = URL.createObjectURL(svgBlob)

    img.onload = () => {
      // 设置白色背景
      ctx.fillStyle = '#ffffff'
      ctx.fillRect(0, 0, width, height)

      // 绘制SVG
      ctx.drawImage(img, 0, 0, width, height)

      // 转换为PNG并下载
      canvas.toBlob((blob) => {
        const pngUrl = URL.createObjectURL(blob)
        const link = document.createElement('a')
        link.href = pngUrl
        link.download = illustration.original_name.replace(/\.svg$/i, '.png')
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)

        URL.revokeObjectURL(pngUrl)
        URL.revokeObjectURL(url)
        nextTick(() => {
          message.success(`已下载 ${illustration.original_name.replace(/\.svg$/i, '.png')}`)
        })
      }, 'image/png')
    }

    img.onerror = () => {
      URL.revokeObjectURL(url)
      nextTick(() => {
        message.error('转换PNG失败')
      })
    }

    img.src = url
  } catch (error) {
    console.error('下载PNG失败:', error)
    nextTick(() => {
      message.error('下载PNG失败')
    })
  }
}

/**
 * 复制成Vue3组件
 */
const handleCopyAsVue3Component = async (illustration) => {
  if (!checkLoginStatus()) return
  if (!illustration) return

  try {
    // 先恢复文档焦点，确保剪贴板API可用
    window.focus()

    const response = await fetch(getIllustrationUrl(illustration.file_path))
    let svgContent = await response.text()

    // 清理SVG内容：移除XML声明和DOCTYPE声明
    svgContent = svgContent
      .replace(/<\?xml[^>]*\?>/g, '') // 移除XML声明
      .replace(/<!DOCTYPE[^>]*>/g, '') // 移除DOCTYPE声明
      .trim() // 移除首尾空白

    // 处理SVG尺寸属性，使其响应式
    svgContent = svgContent.replace(/width="[^"]*"/g, ':width="size"').replace(/height="[^"]*"/g, ':height="size"')

    // 生成Vue3组件代码 - 使用数组方式避免语法冲突
    const lines = []
    lines.push('<!-- Vue3 Illustration Component -->')
    lines.push('<template>')
    lines.push('  <div class="illustration-wrapper" :style="{ width: size + \'px\', height: size + \'px\' }">')
    lines.push('    ' + svgContent)
    lines.push('  </div>')
    lines.push('</template>')
    lines.push('')
    lines.push('<script setup>')
    lines.push('defineProps({')
    lines.push('  size: {')
    lines.push('    type: Number,')
    lines.push('    default: 300')
    lines.push('  }')
    lines.push('})')
    lines.push('</' + 'script>') // 分割避免解析冲突
    lines.push('')
    lines.push('<style scoped>')
    lines.push('.illustration-wrapper {')
    lines.push('  display: inline-flex;')
    lines.push('  align-items: center;')
    lines.push('  justify-content: center;')
    lines.push('}')
    lines.push('</' + 'style>') // 分割避免解析冲突

    const componentCode = lines.join('\n')

    // 使用兼容性更好的复制方法
    await copyToClipboard(componentCode)
    message.success('已复制 ' + illustration.original_name + ' 的Vue3组件代码')
    // 使用 nextTick 确保在 Vue 上下文中调用 message
    nextTick(() => {})
  } catch (error) {
    console.error('复制Vue3组件失败:', error)
    nextTick(() => {
      message.error('复制失败: ' + (error.message || '未知错误'))
    })
  }
}

/**
 * 兼容性剪贴板复制方法
 */
const copyToClipboard = async (text) => {
  // 优先使用现代剪贴板API
  if (navigator.clipboard && window.isSecureContext) {
    try {
      await navigator.clipboard.writeText(text)
      return
    } catch (err) {
      console.warn('Clipboard API failed, falling back to textarea method:', err)
    }
  }

  // 降级方案：使用 textarea
  const textarea = document.createElement('textarea')
  textarea.value = text
  textarea.style.position = 'fixed'
  textarea.style.top = '-9999px'
  textarea.style.left = '-9999px'
  textarea.style.opacity = '0'
  document.body.appendChild(textarea)

  try {
    textarea.select()
    textarea.setSelectionRange(0, text.length)
    const successful = document.execCommand('copy')

    if (!successful) {
      throw new Error('execCommand("copy") failed')
    }
  } finally {
    document.body.removeChild(textarea)
  }
}

/**
 * 阻止图片右键菜单
 */
const preventImageContextMenu = (event) => {
  event.preventDefault()
}

/**
 * 初始化页面数据
 */
const initPageData = () => {
  const categoryId = route.params.categoryId
  const categoryTitle = route.query.title || ''
  const categoryDescription = route.query.description || ''
  const categoryCreatedAt = route.query.created_at || ''

  if (!categoryId) {
    message.error('分类ID不能为空')
    router.push('/illustration-gallery')
    return
  }

  categoryInfo.value = {
    id: categoryId,
    title: categoryTitle,
    description: categoryDescription,
    created_at: categoryCreatedAt
  }

  // 获取数据
  fetchIllustrations()
}

// 监听用户状态变化，动态更新管理员权限
watch(
  () => userStore.user,
  () => {
    checkAdminPermission()
  },
  { immediate: true }
)

// 监听路由变化
watch(
  () => route.params.categoryId,
  () => {
    if (route.name === 'IllustrationDetail') {
      initPageData()
    }
  }
)

// 页面加载时初始化
onMounted(() => {
  initPageData()
})
</script>

<style scoped>
@import './index.css';
</style>
